package com.bkhc.product.service;

import com.bkhc.common.enu.ProductStatusEnum;
import com.bkhc.common.util.MyBeanUtils;
import com.bkhc.common.util.TransObject;
import com.bkhc.common.util.response.PageUtil;
import com.bkhc.common.util.response.ResultCode;
import com.bkhc.common.util.response.ResultJson;
import com.bkhc.product.entity.Goods;
import com.bkhc.product.entity.GoodsSpec;
import com.bkhc.product.entity.Product;
import com.bkhc.product.entity.Spec;
import com.bkhc.product.repository.*;
import org.hibernate.SQLQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class GoodsService {

    @Autowired
    private GoodsRepository repository;

    @PersistenceContext
    private EntityManager entityManager;
    @Autowired
    private GoodspecRepository goodsSpecRepository;

    @Autowired
    private SpecRepository specRepository;
    @Autowired
    private ProductRepository productRepository;



    public ResultJson<?> getGoods(Goods goods, int pageIndex, int pageSize){
        if(goods==null ||CollectionUtils.isEmpty(goods.getGoodsSpec())){
        Sort.Order orders = new Sort.Order(Sort.Direction.DESC, "updateDate");
        PageRequest pageRequest = PageRequest.of(pageIndex-1, pageSize, Sort.by(orders));
        Page<Goods> page = null;
        if(goods == null){
            goods = new Goods();
        }
        goods.setStatus(ProductStatusEnum.Available);
        page  = repository.findAll(goods,pageRequest);
        List<Goods> goodslist = page.getContent();
        if(!CollectionUtils.isEmpty(goodslist)){
            for(Goods item:goodslist){
                item.setGoodsSpec(goodsSpecRepository.findByGoodsCode(item.getGoodsCode()));
            }
        }
            PageUtil pageUtil = new PageUtil(page);
            ResultJson<PageUtil> resultJson = ResultJson.success();
            resultJson.setData(pageUtil);
        return  resultJson;
        }else{
            List<GoodsSpec> goodsSpecs = goods.getGoodsSpec();
            StringBuffer sql = new StringBuffer();
            sql.append("select count(*) from tbl_goods_t t where t.goods_code is not null and t.product_code='") ;
            sql.append(goods.getProductCode()+"'");
            sql.append("  ");
            for(GoodsSpec g:goodsSpecs){
                if(StringUtils.isEmpty(g.getSpecValue())){continue;}
                sql.append("and EXISTS (select * from tbl_goods_spec where");
                sql.append(" spec_code = '");
                sql.append(g.getSpecCode()+"'");
                sql.append(" and ");
                sql.append(" spec_value = '");
                sql.append(g.getSpecValue()+"'");
                sql.append(" and ");
                sql.append(" goods_code =t.goods_code)");
            }

            StringBuffer sqlQuery = new StringBuffer();
            sqlQuery.append("select * from tbl_goods_t t where t.goods_code is not null and t.product_code='") ;
            sqlQuery.append(goods.getProductCode()+"'");
            sqlQuery.append("  ");
            for(GoodsSpec g:goodsSpecs){
                if(StringUtils.isEmpty(g.getSpecValue())){continue;}
                sqlQuery.append("and EXISTS (select * from tbl_goods_spec where");
                sqlQuery.append(" spec_code = '");
                sqlQuery.append(g.getSpecCode()+"'");
                sqlQuery.append(" and ");
                sqlQuery.append(" spec_value = '");
                sqlQuery.append(g.getSpecValue()+"'");
                sqlQuery.append(" and ");
                sqlQuery.append(" goods_code =t.goods_code)");
            }


            Query query = entityManager.createNativeQuery(sql.toString());
            int counts = Integer.valueOf(query.getSingleResult().toString());
            //query.unwrap(SQLQuery.class).setResultTransformer(new TransObject(Goods.class));
            // 设置分页
            Query query1 = entityManager.createNativeQuery(sqlQuery.toString());
            query1.unwrap(SQLQuery.class).setResultTransformer(new TransObject(Goods.class));
            query1.setFirstResult((pageIndex - 1) * pageSize);
            query1.setMaxResults(pageSize);
            // 获取查询结果集
            List<Goods> list = query1.getResultList();
            if(!CollectionUtils.isEmpty(list)){
                for(Goods item:list){
                    item.setGoodsSpec(goodsSpecRepository.findByGoodsCode(item.getGoodsCode()));
                }
            }
            PageUtil pageUtil = new PageUtil();
            pageUtil.setPageNo(pageIndex);
            pageUtil.setTotal(counts);
            pageUtil.setPageSize(pageSize);
            pageUtil.setList(list);
            ResultJson<PageUtil> resultJson = ResultJson.success();
            resultJson.setData(pageUtil);
            return resultJson;
        }

    }


    public ResultJson<?> updateGoodsSpec(List<GoodsSpec> goodsSpecs) {
        if(CollectionUtils.isEmpty(goodsSpecs)){
            ResultJson<Page<Spec>> resultJson = ResultJson.failure(ResultCode.BAD_REQUEST);
            return resultJson;
        }
        for(GoodsSpec s:goodsSpecs){
           GoodsSpec old = goodsSpecRepository.findByGoodsCodeAndSpecCode(s.getGoodsCode(),s.getSpecCode());
            if(old==null){
                goodsSpecRepository.save(s);
            }
            MyBeanUtils.copyProperties(s,old);
            goodsSpecRepository.save(old);
        }
        ResultJson<Page<Goods>> resultJson = ResultJson.success();
        return resultJson;
    }

    public ResultJson<?> deleteGoods(String instanceCode) {
        Goods goods = repository.findByGoodsCode(instanceCode);
        goods.setStatus(ProductStatusEnum.Inactivation);
        ResultJson<Page<Goods>> resultJson = ResultJson.success();
        return resultJson;
    }

    public ResultJson<?> addGoods(Goods goods) {
        Product product = productRepository.findByProductCode(goods.getProductCode());
        goods.setStatus(ProductStatusEnum.Available);
        goods.setProductName(product.getProductName());
        if(CollectionUtils.isEmpty(goods.getGoodsSpec())){
            ResultJson<Page<Spec>> resultJson = ResultJson.failure(ResultCode.BAD_REQUEST);
            return resultJson;
        }

        List<GoodsSpec> goodsSpecs = goods.getGoodsSpec();
        StringBuffer sql = new StringBuffer();
        sql.append("select count(*) from tbl_goods_t t where t.goods_code is not null and t.product_code='") ;
        sql.append(goods.getProductCode()+"'");
        sql.append("  ");
        for(GoodsSpec g:goodsSpecs){
            if(StringUtils.isEmpty(g.getSpecValue())){continue;}
            sql.append("and EXISTS (select * from tbl_goods_spec where");
            sql.append(" spec_code = '");
            sql.append(g.getSpecCode()+"'");
            sql.append(" and ");
            sql.append(" spec_value = '");
            sql.append(g.getSpecValue()+"'");
            sql.append(" and ");
            sql.append(" goods_code =t.goods_code)");
        }
        Query query = entityManager.createNativeQuery(sql.toString());
        int counts = Integer.valueOf(query.getSingleResult().toString());
        if(counts>0){
            ResultJson<Page<Spec>> resultJson = ResultJson.failure(ResultCode.ISEXIT_RESURCE);
            return resultJson;
        }
        repository.save(goods);
        List<GoodsSpec> specs = goods.getGoodsSpec();
        if(!CollectionUtils.isEmpty(specs)){
            for(GoodsSpec item:specs){
                item.setSpecName(specRepository.findBySpecCode(item.getSpecCode()).getSpecName());
                item.setGoodsCode(goods.getGoodsCode());
                goodsSpecRepository.save(item);
            }

        }
        ResultJson<Page<Spec>> resultJson = ResultJson.success();
        return resultJson;
    }

    public ResultJson<?> getGoodsByProduct(String productCode) {
        List<Goods> g = repository.findByProductCode(productCode);
        if(!CollectionUtils.isEmpty(g)){
            List<String> goodsCodes = g.stream().map(Goods::getGoodsCode).collect(Collectors.toList());
            List<GoodsSpec> goodspecList = goodsSpecRepository.findByGoodsCodeIn(goodsCodes);
            for(Goods goods:g){
                List<GoodsSpec> goodspec = goodspecList.stream().filter(x -> x.getGoodsCode().equals(goods.getGoodsCode())).collect(Collectors.toList());
                goods.setGoodsSpec(goodspec);
            }
        }
        ResultJson<List<Goods>> resultJson = ResultJson.success();
        resultJson.setData(g);
        return resultJson;
    }

    public  List<GoodsSpec> getSpecsByGoodsList(List<String> goodsList) {
        List<GoodsSpec> goodspecs = goodsSpecRepository.findByGoodsCodeIn(goodsList);

        return  goodspecs;
    }
}
